package com.bsj.sipgateway.task;

import com.alibaba.fastjson.JSON;
import com.bsj.power.common.config.redis.RedisConstant;
import com.bsj.power.common.def.dto.DeviceRegisterMidDTO;
import com.bsj.power.common.def.entity.DeviceDuration;
import com.bsj.power.common.mapper.DeviceDurationMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.CollectionUtils;
import redis.clients.bsj.JedisClusterBSJ;

import java.util.*;

/**
 * @Description 每天凌晨十二点零一分执行，写入每个设备的当日运行时间
 * @Author zhaoyang
 * @Date 2024/7/11 14:44
 */
@Slf4j
@Configuration
@EnableScheduling
public class RefreshDeviceRegisterMidDTOTask {

    @Autowired
    private JedisClusterBSJ jedisClusterBSJ;

    @Autowired
    private DeviceDurationMapper deviceDurationMapper;

    /**
     * 每隔10分钟执行一次。
     * 定时写入数据库持续时间，要处理的事情
     * 1、计算中间状态的持续时间，写入数据库
     * 2、将注册时间改为定时器开始执行的时间，为下次统计持续时间做准备
     * 线上环境cron改为00：01执行
     */
//    @Scheduled(fixedRate = 1000 * 60 * 10)
    @Scheduled(cron = "0 1 0 1/1 * ?")
    public void refresh() {
        List<DeviceDuration> durations = new ArrayList<>();
        Map<String, String> stringStringMap = jedisClusterBSJ.hgetAll(RedisConstant.DEVICE_REGISTER_MID_DTO);

        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -1);
        Date yesterday = cal.getTime();

        long now = System.currentTimeMillis();

        for (Map.Entry<String, String> entry : stringStringMap.entrySet()) {
            long did = Long.parseLong(entry.getKey());
            String value = entry.getValue();
            DeviceRegisterMidDTO midDTO = JSON.parseObject(value, DeviceRegisterMidDTO.class);

            Long registerTime = midDTO.getRegisterTime();
            Long logoutTime = midDTO.getLogoutTime();
            DeviceDuration deviceDuration = null;
            if (logoutTime == null || logoutTime < registerTime) {
                // 1、logoutTime为null,说明设备注册了，没注销，记录在线时长
                // 2、logoutTime < registerTime 正常注册注销了，然后又注册了，没注销，记录在线时长
                long duration = midDTO.getOnlineTime() + (now - registerTime);
                deviceDuration = new DeviceDuration();
                deviceDuration.setDid(did);
                deviceDuration.setDeviceId(midDTO.getDeviceId());
                deviceDuration.setRunDate(yesterday);
                deviceDuration.setDurationTime(duration);
                durations.add(deviceDuration);
                // 当天持续时间归零
                midDTO.setOnlineTime(0L);
                midDTO.setRegisterTime(now); // 将设备注册时间调整为现在
            } else {
                // logoutTime > registerTime 说明设备正常注册注销了，只写入持续时间即可，不改变注册时间和注销时间，下次就不会统计了
                long onlineTime = midDTO.getOnlineTime();
                if (onlineTime != 0) {
                    deviceDuration = new DeviceDuration();
                    deviceDuration.setDid(did);
                    deviceDuration.setDeviceId(midDTO.getDeviceId());
                    deviceDuration.setRunDate(yesterday);
                    deviceDuration.setDurationTime(onlineTime);
                    durations.add(deviceDuration);
                    midDTO.setOnlineTime(0L);
                    // 这里不修改注册时间了
                }
            }
            jedisClusterBSJ.hset(RedisConstant.DEVICE_REGISTER_MID_DTO, did + "", JSON.toJSONString(midDTO));
        }
        if (!CollectionUtils.isEmpty(durations)) {
            deviceDurationMapper.addAll(durations);
        }
    }

}
